package moe.service;

import java.io.File;
import java.io.UnsupportedEncodingException;
import java.lang.reflect.Method;
import java.util.Map;
import java.util.logging.Logger;

import moe.config.Configuration;
import moe.dao.BaseDao;
import moe.dao.CollectionDao;
import moe.entity.Collection;
import moe.entity.Post;
import moe.server.StaticResourcesHandler;

import org.apache.http.HttpHeaders;
import org.apache.http.HttpResponse;
import org.apache.http.HttpStatus;
import org.apache.http.entity.StringEntity;
import org.apache.http.protocol.HttpContext;

public class CollectionHandler extends AbstractHandler {

	private static class DelegatePostHandler extends PostHandler {
		private StaticResourcesHandler staticResourcesHandler = new StaticResourcesHandler();;

		public DelegatePostHandler() {
			super(BaseDao.ConnType.COLLECTION);
		}

		@Override
		protected void sendJsonResponse(HttpResponse response, String json) {
			super.sendJsonResponse(response, json);
			if (response.getStatusLine().getStatusCode() == HttpStatus.SC_OK) {
				/*
				 * prevent reiteration create thumbnail
				 */
				response.addHeader(HttpHeaders.CACHE_CONTROL, "no-cache");
			}
		}

		@Override
		protected void resolveUrl(Post post) {
			super.resolveUrl(post);
			resolveCollectionUrl(post);
		}

		private void resolveCollectionUrl(Post post) {
			Collection collection = collectionDao.getCollection(post.id);
			try {
				Method method = StaticResourcesHandler.class.getDeclaredMethod("resolveFilePath",
						String.class);
				method.setAccessible(true);
				String path = (String) method.invoke(staticResourcesHandler, post.previewUrl);
				if (!new File(path).exists()) {
					File file = new File(PREVIEW_DIR, "thumbnail." + collection.getName());
					if (file.exists()) {
						post.previewUrl = "/collection/preview/" + file.getName();
					} else if (Configuration.isCreateThumbnails()) {
						post.previewUrl = "/collection/convert" + post.fileUrl;
					}
				}
			} catch (Exception e) {
				if (Configuration.isCreateThumbnails()) {
					post.previewUrl = "/collection/convert" + post.fileUrl;
				}
			}
			post.fileUrl = "/collection" + post.fileUrl;
			post.source = collection.getFilePath();
		}
	}

	private static final Logger log = Logger.getLogger(CollectionHandler.class.getName());
	private static final String PREVIEW_DIR = System.getProperty("user.dir") + File.separator
			+ "preview" + File.separator;
	private static CollectionDao collectionDao = new CollectionDao();
	private DelegatePostHandler delegatePostHandler;

	public CollectionHandler() {
		delegatePostHandler = new DelegatePostHandler();
	}

	public void listCollections(HttpContext context, Map<String, String[]> query) {
		delegatePostHandler.listPosts(context, query);
	}

	public void searchCollections(HttpContext context, Map<String, String[]> query) {
		delegatePostHandler.searchPosts(context, query);
	}

	public void collectCollectionsPost(HttpContext context, Map<String, String[]> query) {
		delegatePostHandler.collectPost(context, query);
	}

	public void deleteCollection(HttpContext context, Map<String, String[]> query) {
		HttpResponse response = getHttpResponse(context);
		if (!query.containsKey("id")) {
			response.setStatusCode(HttpStatus.SC_BAD_REQUEST);
			return;
		}
		long id = Long.valueOf(query.get("id")[0]);
		Collection collection = collectionDao.getCollection(id);
		collectionDao.deleteCollection(id);
		String[] paths = new String[] {
				collection.getFilePath(),
				PREVIEW_DIR + "thumbnail." + collection.getName()
		};
		boolean result = deleteFiles(paths);

		try {
			String msg = "success";
			if (!result) {
				msg = "fail";
			}
			response.setEntity(new StringEntity(msg, "text/plain",
					"UTF-8"));
		} catch (UnsupportedEncodingException e) {
			response.setStatusCode(HttpStatus.SC_INTERNAL_SERVER_ERROR);
			return;
		}
	}

	private boolean deleteFiles(String[] files) {
		boolean result = true;
		for (String path : files) {
			result = deleteFile(path);
		}
		return result;
	}

	private boolean deleteFile(String path) {
		boolean result = true;
		try {
			new File(path).delete();
		} catch (Exception e) {
			result = false;
			log.warning("Can't delete the file(\"" + path + "\"):" + e.getMessage());
		}
		return result;
	}
}
